package com.waikuai.shop.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.waikuai.shop.dto.ShippingAddressDTO;
import com.waikuai.shop.entity.ShippingAddress;
import com.waikuai.shop.mapper.ShippingAddressMapper;
import com.waikuai.shop.service.ShippingAddressService;
import com.waikuai.shop.vo.ShippingAddressVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 收货地址服务实现类
 * @author waikuai
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ShippingAddressServiceImpl extends ServiceImpl<ShippingAddressMapper, ShippingAddress> implements ShippingAddressService {

    private final ShippingAddressMapper shippingAddressMapper;

    /**
     * 最大收货地址数量限制
     */
    private static final int MAX_ADDRESS_COUNT = 5;

    @Override
    public List<ShippingAddressVO> getUserAddressList(Long userId) {
        List<ShippingAddress> addresses = shippingAddressMapper.selectByUserId(userId);
        return addresses.stream()
                .map(this::convertToVO)
                .collect(Collectors.toList());
    }

    @Override
    public ShippingAddressVO getAddressById(Long id, Long userId) {
        ShippingAddress address = shippingAddressMapper.selectByIdAndUserId(id, userId);
        if (address == null) {
            return null;
        }
        return convertToVO(address);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ShippingAddressVO addAddress(Long userId, ShippingAddressDTO dto) {
        // 检查地址数量限制
        Integer count = shippingAddressMapper.countByUserId(userId);
        if (count >= MAX_ADDRESS_COUNT) {
            throw new RuntimeException("收货地址最多只能添加" + MAX_ADDRESS_COUNT + "个");
        }

        // 创建新地址
        ShippingAddress address = new ShippingAddress();
        BeanUtils.copyProperties(dto, address);
        address.setUserId(userId);

        // 如果设置为默认地址，先取消其他默认地址
        if (dto.getIsDefault() != null && dto.getIsDefault() == 1) {
            shippingAddressMapper.cancelAllDefaultAddress(userId);
        } else {
            // 如果是第一个地址，自动设为默认
            if (count == 0) {
                address.setIsDefault(1);
            } else {
                address.setIsDefault(0);
            }
        }

        // 保存地址
        shippingAddressMapper.insert(address);
        log.info("新增收货地址成功，用户ID: {}, 地址ID: {}", userId, address.getId());

        return convertToVO(address);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateAddress(Long id, Long userId, ShippingAddressDTO dto) {
        // 检查地址是否存在
        ShippingAddress existingAddress = shippingAddressMapper.selectByIdAndUserId(id, userId);
        if (existingAddress == null) {
            throw new RuntimeException("收货地址不存在");
        }

        // 更新地址信息
        ShippingAddress address = new ShippingAddress();
        BeanUtils.copyProperties(dto, address);
        address.setId(id);
        address.setUserId(userId);

        // 如果设置为默认地址，先取消其他默认地址
        if (dto.getIsDefault() != null && dto.getIsDefault() == 1) {
            shippingAddressMapper.cancelAllDefaultAddress(userId);
        }

        int result = shippingAddressMapper.updateById(address);
        if (result > 0) {
            log.info("更新收货地址成功，用户ID: {}, 地址ID: {}", userId, id);
            return true;
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteAddress(Long id, Long userId) {
        // 检查地址是否存在
        ShippingAddress address = shippingAddressMapper.selectByIdAndUserId(id, userId);
        if (address == null) {
            throw new RuntimeException("收货地址不存在");
        }

        // 软删除地址
        int result = shippingAddressMapper.deleteById(id);
        
        // 如果删除的是默认地址，将第一个地址设为默认
        if (result > 0 && address.getIsDefault() == 1) {
            List<ShippingAddress> addresses = shippingAddressMapper.selectByUserId(userId);
            if (!addresses.isEmpty()) {
                ShippingAddress firstAddress = addresses.get(0);
                shippingAddressMapper.setAsDefault(firstAddress.getId(), userId);
                log.info("删除默认地址后，自动设置新的默认地址，用户ID: {}, 新默认地址ID: {}", userId, firstAddress.getId());
            }
        }

        if (result > 0) {
            log.info("删除收货地址成功，用户ID: {}, 地址ID: {}", userId, id);
            return true;
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean setDefaultAddress(Long id, Long userId) {
        // 检查地址是否存在
        ShippingAddress address = shippingAddressMapper.selectByIdAndUserId(id, userId);
        if (address == null) {
            throw new RuntimeException("收货地址不存在");
        }

        // 先取消所有默认地址
        shippingAddressMapper.cancelAllDefaultAddress(userId);

        // 设置为默认地址
        int result = shippingAddressMapper.setAsDefault(id, userId);
        if (result > 0) {
            log.info("设置默认地址成功，用户ID: {}, 地址ID: {}", userId, id);
            return true;
        }
        return false;
    }

    @Override
    public ShippingAddressVO getDefaultAddress(Long userId) {
        ShippingAddress address = shippingAddressMapper.selectDefaultAddress(userId);
        if (address == null) {
            return null;
        }
        return convertToVO(address);
    }

    @Override
    public int countUserAddresses(Long userId) {
        Integer count = shippingAddressMapper.countByUserId(userId);
        return count != null ? count : 0;
    }

    /**
     * 将实体转换为VO
     */
    private ShippingAddressVO convertToVO(ShippingAddress address) {
        ShippingAddressVO vo = new ShippingAddressVO();
        BeanUtils.copyProperties(address, vo);
        
        // 构建完整地址
        vo.setFullAddress(buildFullAddress(address));
        
        return vo;
    }

    /**
     * 构建完整地址
     */
    private String buildFullAddress(ShippingAddress address) {
        StringBuilder sb = new StringBuilder();
        if (address.getProvince() != null) {
            sb.append(address.getProvince());
        }
        if (address.getCity() != null) {
            sb.append(address.getCity());
        }
        if (address.getDistrict() != null) {
            sb.append(address.getDistrict());
        }
        if (address.getDetailedAddress() != null) {
            sb.append(address.getDetailedAddress());
        }
        return sb.toString();
    }
}

